﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.IO;
using SpectationClient.DataBaseDescription;

namespace SpectationClient.SpectralTools {
    
    /// <summary>
    /// This class defines a single spectrum that tries to include all aspects of ASD, ESL or other formats
    /// </summary>
    /// 
    public class Spectrum {
        #region static definitions
        public enum SpectrumType : byte {
            RAW_TYPE = 0,
            REF_TYPE = 1,
            RAD_TYPE = 2,
            NOUNITS_TYPE = 3,
            IRRAD_TYPE = 4,
            QI_TYPE = 5,
            TRANS_TYPE = 6,
            UNKNOWN_TYPE = 7,
            ABS_TYPE = 8
        }

        public enum SpectrumFileType : byte {
            ASD = 0,
            ESL = 1,
        }

        public static String SpecType2String(SpectrumType spectrumType) { 
            switch (spectrumType) {
                case SpectrumType.ABS_TYPE: return "ABS";
                case SpectrumType.IRRAD_TYPE: return "IRRAD";
                case SpectrumType.NOUNITS_TYPE: return "N/A";
                case SpectrumType.QI_TYPE: return "QI";
                case SpectrumType.RAD_TYPE: return "RAD";
                case SpectrumType.RAW_TYPE: return "RAW";
                case SpectrumType.REF_TYPE: return "REF";
                case SpectrumType.TRANS_TYPE: return "TRANS";
                case SpectrumType.UNKNOWN_TYPE: return "N/A";
            }
            return "unknown";
        }

        public enum InstrumentType : byte {
            UNKNOWN = 0,
            PSII = 1,
            LSVNIR = 2,
            FSVNIR = 3,
            FSFR = 4,
            FSNIR = 5,
            CHEMT = 6,
            FSFR_UNATTENDED = 7,

            //Plane
            HyMap = 100,
            //Satelite

            EnMAP = 201,
            Landsat_TM = 202,
            Landsat_ETMPlus = 203
        }

        public bool Equals(Spectrum spectrum) {
            return this.FileName == spectrum.FileName &&
                   this.SpectrumName == spectrum.SpectrumName &&
                   this.NumberOfBands == spectrum.NumberOfBands;
        }

        public static String InstrumentTypeString(InstrumentType instrumentType) { 
            switch (instrumentType) {
                case InstrumentType.CHEMT: return "CHEMT";
                case InstrumentType.FSFR: return "FSFR";
                case InstrumentType.FSFR_UNATTENDED: return "FSFR UNATTENDED";
                case InstrumentType.FSNIR: return "FSNIR";
                case InstrumentType.FSVNIR: return "FSVNIR";
                case InstrumentType.HyMap: return "HyMAP";
                case InstrumentType.EnMAP: return "EnMAP";
                case InstrumentType.LSVNIR: return "LSVNIR";
                case InstrumentType.PSII: return "PSII";
                case InstrumentType.UNKNOWN: return "unknown";
            }
            return "unknown";
        }

        #endregion

        #region Fields & Getters
        private String comments;
        public String Comments {
            get { return this.comments; }
            set {this.comments = value.Trim(new Char[]{'\r','\n','\0',' '}); } 
        }
        public String FileName { get; set; }
        public String SpectrumName { get; set; }
        public SpectrumType SpecType { get; set; }
        public String SpecTypeString { get { return Spectrum.SpecType2String(this.SpecType); } }
        public InstrumentType IntrumentType { get; set; }
        public DateTime? TimeSaved { get; set;}
        public Type DataType { get; set;}
        public String WaveLengthUnit { get; set; }
        /// <summary>
        /// Returns the data type as short string (e.g. "Double" instead of "System.Double")
        /// </summary>
        public String DataTypeString { 
            get { return System.Text.RegularExpressions.Regex.Match(this.DataType.ToString(),"[^.]+$").Value; } 
        }

        /// <summary>
        /// File Type of Spectrum.
        /// </summary>
        public SpectrumFileType FileType { get; set; }
        
        /// <summary>
        /// File Type of Spectrum as string description.
        /// </summary>
        public String FileTypeString { get { return Enum.GetName(typeof(SpectrumFileType), this.FileType); } }
        
        /// <summary>
        /// Full width attributes half maximum (FWHM) definition for each band
        /// </summary>
        public Single[] BandFWHM {get; set;}

        /// <summary>
        /// Array with spectral values measured for each band.
        /// </summary>
        public Single[] BandValues { get; set; }
        public Single[] Bands { get; set; }

        public Boolean[] BadBands { get; set; }

        public int NumberOfBands {get{return Bands.Length;}}
        public int? SensorID { get; set; }
        public int? SensorCalibrationNumber { get; set; }

        public Single WL_Min { get { return Bands.First(); } }
        public Single WL_Max { get { return Bands.Last(); } }
        public Byte[] originalASD_BLOB { get; set; }

        /// <summary>
        /// Use this to add a tag.
        /// </summary>
        public Object Tag { get;set; }
        #endregion
        //private PointPairList ppl = new PointPairList();
        

        private Char[] toRemove = { '\0' };

#region Factories


        
#endregion

#region Constructors
        
        public Spectrum(String name){
            this.SpectrumName = name;
        
        }
#endregion
      

      
    }
}
